{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "states = [\"Rainy\", \"Sunny\"]\n",
    "n_states = len(states)\n",
    "\n",
    "observations = [\"walk\", \"shop\", \"clean\"]\n",
    "n_observations = len(observations)\n",
    "\n",
    "# initial probability\n",
    "phi = np.array([0.6, 0.4])\n",
    "\n",
    "# transition probability\n",
    "A = np.array([[0.7, 0.3],\n",
    "              [0.4, 0.6]])\n",
    "\n",
    "# observation probability\n",
    "B = np.array([[0.2, 0.3, 0.5],\n",
    "              [0.5, 0.4, 0.1]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tiga permasalahan di HMM\n",
    "1. Evaluation, masukannya Observation (O) dan lambda (phi, A, B) -> likelihood P(O | lambda)\n",
    "2. Decoding, masukannya Observation (O) dan lambda -> State sequence S = {S1, S2, ..., Sn}\n",
    "3. Learning, masukannya Observation (O) -> return phi, A, B terbaik berdasarkan nilai likelihood P(O | lambda)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# hmmlearn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from hmmlearn import hmm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# initialize hmm\n",
    "m_hmmlearn = hmm.MultinomialHMM(n_components=n_states)\n",
    "m_hmmlearn.startprob = phi\n",
    "m_hmmlearn.transmat = A\n",
    "m_hmmlearn.emissionprob = B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# observation sequence\n",
    "obs_seq = np.array([[0, 2, 1, 0, 1, 0, 0]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# learning\n",
    "m_hmmlearn = m_hmmlearn.fit(obs_seq)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([7.09899657e-09, 9.99999993e-01])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m_hmmlearn.startprob_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.36565375, 0.63434625],\n",
       "       [0.74761594, 0.25238406]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m_hmmlearn.transmat_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.110307  , 0.59442058, 0.29527242],\n",
       "       [0.9841646 , 0.00940058, 0.00643482]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m_hmmlearn.emissionprob_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "log_prob, best_path = m_hmmlearn.decode(obs_seq.T, algorithm='viterbi')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-6.198965880784751"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "log_prob"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 0, 0, 1, 0, 1, 1])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "best_path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 0, 0, 1, 0, 1, 1])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m_hmmlearn.predict(obs_seq.T)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# pomegranate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pomegranate import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# initialize hmm\n",
    "m_pomegranate = HiddenMarkovModel()\n",
    "\n",
    "# definisikan state\n",
    "rainy = State(DiscreteDistribution({'walk': 0.2, 'shop': 0.3, 'clean': 0.5}), name='Rainy')\n",
    "sunny = State(DiscreteDistribution({'walk': 0.5, 'shop': 0.4, 'clean': 0.1}), name='Sunny')\n",
    "\n",
    "# initial probability\n",
    "m_pomegranate.add_transition(m_pomegranate.start, rainy, 0.6)\n",
    "m_pomegranate.add_transition(m_pomegranate.start, sunny, 0.4)\n",
    "\n",
    "# transition probability\n",
    "m_pomegranate.add_transition(rainy, rainy, 0.7)\n",
    "m_pomegranate.add_transition(rainy, sunny, 0.3)\n",
    "m_pomegranate.add_transition(sunny, rainy, 0.4)\n",
    "m_pomegranate.add_transition(sunny, sunny, 0.6)\n",
    "\n",
    "m_pomegranate.bake()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# observation sequence\n",
    "obs_seq_str = ['walk', 'clean', 'shop', 'walk', 'shop', 'walk', 'walk']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 0, 0, 1, 1, 1, 1]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m_pomegranate.predict(obs_seq_str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-7.709129800619791"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m_pomegranate.log_probability(obs_seq_str)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Latihan\n",
    "- States = Sunny, Rainy, Cloudy, Foggy\n",
    "- Observations = Umbrella, Not Umbrella"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
